import static org.junit.Assert.*;

import java.awt.*;
import javax.swing.*;

import org.junit.Test;
import org.mockito.Mockito;

import java.awt.event.*;

public class Calculator extends JFrame implements ActionListener {
    
    
	JPanel[] row = new JPanel[5];
    JButton[] button = new JButton[19];
    String[] buttonString = {"7", "8", "9", "+",
                             "4", "5", "6", "-",
                             "1", "2", "3", "*",
                             ".", "/", "C", "√",
                             "+/-", "=", "0"};
    int[] dimW = {300,45,100,90};
    int[] dimH = {35, 40};
    Dimension displayDimension = new Dimension(dimW[0], dimH[0]);
    Dimension regularDimension = new Dimension(dimW[1], dimH[1]);
    Dimension rColumnDimension = new Dimension(dimW[2], dimH[1]);
    Dimension zeroButDimension = new Dimension(dimW[3], dimH[1]);
    boolean[] function = new boolean[4];
    double[] temporary = {0, 0};
    JTextArea display = new JTextArea(1,20);
    Font font = new Font("Times new Roman", Font.BOLD, 14);
    
    public Calculator() {
        super("Calculator");
        setDesign();
        setSize(380, 250);
        setResizable(false);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        GridLayout grid = new GridLayout(5,5);
        setLayout(grid);
        
        for(int i = 0; i < 4; i++)
            function[i] = false;
        
        FlowLayout f1 = new FlowLayout(FlowLayout.CENTER);
        FlowLayout f2 = new FlowLayout(FlowLayout.CENTER,1,1);
        for(int i = 0; i < 5; i++)
            row[i] = new JPanel();
        row[0].setLayout(f1);
        for(int i = 1; i < 5; i++)
            row[i].setLayout(f2);
        
        for(int i = 0; i < 19; i++) {
            button[i] = new JButton();
            button[i].setText(buttonString[i]);
            button[i].setFont(font);
            button[i].addActionListener(this);
        }
        
        display.setFont(font);
        display.setEditable(false);
        display.setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);
        display.setPreferredSize(displayDimension);
        for(int i = 0; i < 14; i++)
            button[i].setPreferredSize(regularDimension);
        for(int i = 14; i < 18; i++)
            button[i].setPreferredSize(rColumnDimension);
        button[18].setPreferredSize(zeroButDimension);
        
        row[0].add(display);
        add(row[0]);
        
        for(int i = 0; i < 4; i++)
            row[1].add(button[i]);
        row[1].add(button[14]);
        add(row[1]);
        
        for(int i = 4; i < 8; i++)
            row[2].add(button[i]);
        row[2].add(button[15]);
        add(row[2]);
        
        for(int i = 8; i < 12; i++)
            row[3].add(button[i]);
        row[3].add(button[16]);
        add(row[3]);
        
        row[4].add(button[18]);
        for(int i = 12; i < 14; i++)
            row[4].add(button[i]);
        row[4].add(button[17]);
        add(row[4]);
        
        setVisible(true);
    }
    
    public void clear() {
        try {
            display.setText("");
            for(int i = 0; i < 4; i++)
                function[i] = false;
            for(int i = 0; i < 2; i++)
                temporary[i] = 0;
        } catch(NullPointerException e) {  
        }
    }
    
    public void getSqrt() {
        try {
            double value = Math.sqrt(Double.parseDouble(display.getText()));
            display.setText(Double.toString(value));
        } catch(NumberFormatException e) {
        }
    }
    
    public void getPosNeg() {
        try {
            double value = Double.parseDouble(display.getText());
            if(value != 0) {
                value = value * (-1);
                display.setText(Double.toString(value));
            }
            else {
            }
        } catch(NumberFormatException e) {
        }
    }
    
    public void mock_getResult() {
    	double result = 321;
    	display.setText(Double.toString(result));
    }
    
    public void getResult() {
        double result = 0;
        temporary[1] = Double.parseDouble(display.getText());
        String temp0 = Double.toString(temporary[0]);
        String temp1 = Double.toString(temporary[1]);
        try {
            if(temp0.contains("-")) {
                String[] temp00 = temp0.split("-", 2);
                temporary[0] = (Double.parseDouble(temp00[1]) * -1);
            }
            if(temp1.contains("-")) {
                String[] temp11 = temp1.split("-", 2);
                temporary[1] = (Double.parseDouble(temp11[1]) * -1);
            }
        } catch(ArrayIndexOutOfBoundsException e) {
        }
        try {
            if(function[2] == true)
                result = temporary[0] * temporary[1];
            else if(function[3] == true)
                result = temporary[0] / temporary[1];
            else if(function[0] == true)
                result = temporary[0] + temporary[1];
            else if(function[1] == true)
                result = temporary[0] - temporary[1];
            display.setText(Double.toString(result));
            for(int i = 0; i < 4; i++)
                function[i] = false;
        } catch(NumberFormatException e) {
        }
    }
    
    public final void setDesign() {
        try {
            UIManager.setLookAndFeel(
                    "com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel");
        } catch(Exception e) {   
        }
    }
    
    @Override
    public void actionPerformed(ActionEvent ae) {
        if(ae.getSource() == button[0])
            display.append("7");
        if(ae.getSource() == button[1])
            display.append("8");
        if(ae.getSource() == button[2])
            display.append("9");
        if(ae.getSource() == button[3]) {
            //add function[0]
            temporary[0] = Double.parseDouble(display.getText());
            function[0] = true;
            display.setText("");
        }
        if(ae.getSource() == button[4])
            display.append("4");
        if(ae.getSource() == button[5])
            display.append("5");
        if(ae.getSource() == button[6])
            display.append("6");
        if(ae.getSource() == button[7]) {
            //subtract function[1]
            temporary[0] = Double.parseDouble(display.getText());
            function[1] = true;
            display.setText("");
        }
        if(ae.getSource() == button[8])
            display.append("1");
        if(ae.getSource() == button[9])
            display.append("2");
        if(ae.getSource() == button[10])
            display.append("3");
        if(ae.getSource() == button[11]) {
            //multiply function[2]
            temporary[0] = Double.parseDouble(display.getText());
            function[2] = true;
            display.setText("");
        }
        if(ae.getSource() == button[12])
            display.append(".");
        if(ae.getSource() == button[13]) {
            //divide function[3]
            temporary[0] = Double.parseDouble(display.getText());
            function[3] = true;
            display.setText("");
        }
        if(ae.getSource() == button[14])
            clear();
        if(ae.getSource() == button[15])
            getSqrt();
        if(ae.getSource() == button[16])
            getPosNeg();
        if(ae.getSource() == button[17])
            getResult();
        if(ae.getSource() == button[18])
            display.append("0");
    }
    
    public static void main(String[] arguments) {
    	Calculator c = new Calculator();
    }
    
  /*  	 
    @Test  
    public void test_getPosNeg(){
    	display.setText("1");
    	getPosNeg();
    	assertTrue(display.getText().equals("-1.0"));
    }
 
    @Test  
    public void test_getSqrt(){
    	display.setText("16");
    	getSqrt();
    	assertTrue(display.getText().equals("4.0"));
    }

    @Test  
    public void testClear(){
    	display.setText("333");
    	clear();
    	assertTrue(display.getText().equals(""));
    }
   
    @Test  
    public void testAddPositive(){
    	display.setText("1");
    	temporary[0] = 1;
    	function[0] = true;
    	getResult();
    	assertTrue(display.getText().equals("2.0"));
    }
    
    @Test
    public void testAddNegative(){
    	display.setText("3");
    	temporary[0] = -1;
    	function[0] = true;
    	getResult();
    	assertTrue(display.getText().equals("2.0"));
    }
    
    @Test
    public void testSubNegative(){
    	display.setText("-1");
    	temporary[0] = 1;
    	function[1] = true;
    	getResult();
    	assertTrue(display.getText().equals("2.0"));
    }
    
    @Test
    public void testSubPositive(){
    	display.setText("6");
    	temporary[0] = 2;
    	function[1] = true;
    	getResult();
    	assertTrue(display.getText().equals("-4.0"));
    }
    
    @Test
    public void testMultZero(){
    	display.setText("5");
    	temporary[0] = 0;
    	function[2] = true;
    	getResult();
    	assertTrue(display.getText().equals("0.0"));
    }
        
    @Test
    public void testDivide(){
    	display.setText("3");
    	temporary[0] = 6;
    	function[3] = true;
    	getResult();
    	assertTrue(display.getText().equals("2.0"));
    }   
    
    @Test
    public void testDivideZero(){
    	display.setText("0");
    	temporary[0] = 6;
    	function[3] = true;
    	getResult();
    	assertTrue(display.getText().equals("Infinity"));
    }
        
    @Test
    public void testClickAndDisplay0(){   	
    	ActionEvent action = new ActionEvent(button[0], 1, "");    	
    	this.actionPerformed(action);   	
    	assertTrue(display.getText().equals("7"));
    	
    }
    
    @Test
    public void testClickAndDisplay1(){   	
    	ActionEvent action = new ActionEvent(button[1], 1, "");    	
    	this.actionPerformed(action);    	
    	assertTrue(display.getText().equals("8"));
    	
    }
    
    @Test
    public void testClickAndDisplay2(){   	
    	ActionEvent action = new ActionEvent(button[2], 1 , "");    	
    	this.actionPerformed(action);    	
    	assertTrue(display.getText().equals("9"));
    }
 
    @Test
    public void testClickAndDisplay3(){   	
    	ActionEvent action = new ActionEvent(button[3], 1, "");    	    	
    	display.append("123");
    		this.actionPerformed(action);
        assertTrue(temporary[0] == 123); 
        assertTrue(function[0] == true);
    	assertEquals("should be empty",display.getText(), ""); 	
    }        
    
    @Test
    public void testClickAndDisplay4(){   	
    	ActionEvent action = new ActionEvent(button[4], 1, "");    	
    	this.actionPerformed(action); 
    	assertEquals("", "4", "4");
    	assertSame("", "4", "4");
    }
  
    @Test
    public void testClickAndDisplay5(){   	
    	ActionEvent action = new ActionEvent(button[5], 1, "");    	
    	this.actionPerformed(action); 
    	//assertEquals("", "4", "4");
    	assertSame("", "5", "5");
    }
    
    @Test
    public void testClickAndDisplay6(){   	
    	ActionEvent action = new ActionEvent(button[6], 1, "");    	
    	this.actionPerformed(action); 
    	assertEquals("", "6", "6");
    }

    @Test
    public void testClickAndDisplay7(){   	
    	ActionEvent action = new ActionEvent(button[7], 1, "");    	    	
    	display.append("123");
    		this.actionPerformed(action);
        assertTrue(temporary[0] == 123); 
        assertTrue(function[1] == true);
    	assertEquals("should be empty",display.getText(), ""); 	
    }       
  
    @Test
    public void testClickAndDisplay8(){   	
    	ActionEvent action = new ActionEvent(button[8], 1, "");    	
    	this.actionPerformed(action); 
    	assertEquals("", "8", "8");
    }
    
    @Test
    public void testClickAndDisplay9(){   	
    	ActionEvent action = new ActionEvent(button[9], 1, "");    	
    	this.actionPerformed(action); 
    	assertEquals("", "9", "9");
    }
    
    @Test
    public void testClickAndDisplay10(){   	
    	ActionEvent action = new ActionEvent(button[10], 1, "");    	
    	this.actionPerformed(action); 
    	assertEquals("", "10", "10");
    }
    
    @Test
    public void testClickAndDisplay11(){   	
    	ActionEvent action = new ActionEvent(button[11], 1, "");
    	display.append("123");
    	this.actionPerformed(action); 
    	assertEquals("should be empty",display.getText(), "");
    }    
    
    @Test
    public void testClickAndDisplay12(){   	
    	ActionEvent action = new ActionEvent(button[12], 1, "");    	
    	this.actionPerformed(action); 
    	assertEquals("", ".", ".");
    }   
  
    @Test
    public void testClickAndDisplay13(){   	
    	ActionEvent action = new ActionEvent(button[13], 1, "");
    	display.append("123");
    	this.actionPerformed(action); 
    	assertEquals("should be empty",display.getText(), "");
    }    
    
    @Test
    public void testClickAndDisplay14(){   	
    	ActionEvent action = new ActionEvent(button[14], 1, "");    	
    	this.actionPerformed(action); 
    	assertEquals("should be empty",display.getText(), "");
    }   

    @Test
    public void testClickAndDisplay15(){   	
    	ActionEvent action = new ActionEvent(button[15], 1, "");
    	display.append("36");
    	this.actionPerformed(action); 
    	assertEquals("should be empty",display.getText(), "6.0");
    }   
    
    @Test
    public void testClickAndDisplay16(){   	
    	ActionEvent action = new ActionEvent(button[16], 1, "");
    	display.append("36");
    	this.actionPerformed(action); 
    	assertEquals("should be empty",display.getText(), "-36.0");
    }   
 
    @Test
    public void testClickAndDisplay17(){   	
    	//ActionEvent action = new ActionEvent(button[15], 1, "");
    	
    	Calculator test = Mockito.mock(Calculator.class);
    	//test.when(test.getResult()).thenReturn(22);
    	//display.append("36");
    	//this.actionPerformed(action); 
    	//assertEquals("should be empty",display.getText(), "");
    }   
*/    
}

